clear % clear all variables
clc % clear Command Window
close all % close all popups

MSDF=20;%When calculating the MSD only tracks of length greater than MSDF
MSDL=20;% When calculating the short and average MSD  only the first MSDL values as given

Ynpixels=512; % number of pixels on the y-axis
Xnpixels=512;% number of pixels on the x-axis

Num=10;% This is the number of frames over which a section of a track is analysed over.If a track is Num+3 frames long then
%The particle will be analysed over frames 1-Num,2-Num+1,3-Num+3

%-----------------------Section1----------------------------------------------------------------------------------------------
%The for loop below is to carry out the proccess on NT different  tracking
%files
counter2=1;
tempI=1;
tempA=1;


Plotyes=1;% If this =1 then matlab plots are taken, which show particle tracks
FA=3; % this is the highest angle which points into one of the  flow directions. This is used to identify which partcile are moving parralel or anti-parralel 
ET=',No Drive'; %this text is inserted into the end of certain and plot graph titles
ET2='  '; %this text is inserted inside certain  graph and plot titles
ET3=', Amplitude of Translation '; %this text is inserted inside certain  graph and plot titles
ET4=' '; %this text is inserted inside certain  graph and plot titles
NT=1;%Number of seperate files to be looked at.






mindisp=10;% This is the minimum dispalcement a particle must travel before its correlrated angle of trajectory is examined.Assuming the track length is also long enough.
mindisp2=10;% This is the minimum dispalcement a particle must travel before its overall trajecroy is examined.Assuming the track length is also long enough.
fps=23;% Frames Per second of the tif file,used in calculating the speed and lag time interval.
LagTI=1/fps;% lag time interval

mp=0.25;%microns/pixel. This is a correction factor to convert from pixels to microns.
F=20;% This is a Filter which removes tracks that have a maximum displacement greater than F*the number of frames in the window of analysis ( F has units of microns/Frame)
% This is to deal with an error which rarely occurs where the tracking program  thinks a
% particle has jumped way to far due to a case of mistaken identitiy, it
% becomes more important as max disp increases and as the conencentration
% increases

%-----------------------------------------Section2-----------------------
%Insert file names below, If the video you are analysing was broken up into
%5 clips then there would be 5 files to insert below
%------------------------------------------------------------------------------------------------------------------------------------------------------
for round=1:NT
 %------------------------------------------------------------------------------------------------------------------------------------------------------
  time=1
  
     
     if round==1;
A =load ('QD-AP(3) FmocFpY t=25mins 100x');%
    end 
        
       if round==2;
A =load ('2Result of S4_200fps_GD300_ABS_NODRIVE0253_amp1f1centre_t.dat');%
    end 
        
        if round==3;
A =load ('3Result of S4_200fps_GD300_ABS_NODRIVE0253_amp1f1centre_t.dat');% 
    end 
        
        if round==4;
A =load ('4Result of S4_200fps_GD300_ABS_NODRIVE0253_amp1f1centre_t.dat');% 
        end 
        
     if round==5;
A =load ('2p5n3');% 
    end 
     if round==6;
A =load ('2p5n4');% 
     end 
     
        if round==7;
A =load ('2p5n5');% 
        end 
     
        if round==8;
A =load ('2ndnewd');% 
        end 
        
        if round==9;
A =load ('3rdnewd');% 
     end 
     
        if round==10;
A =load ('5thnewd');% 
     end 
     
     
     if round==11;
A =load ('r22p5n1');%
    end 
        
       if round==12;
A =load ('r22p5n2');%
    end 
        
        if round==13;
A =load ('r22p5n3');% 
    end 
        
        if round==14;
A =load ('r22p5n4');% 
        end 
        
     if round==15;
A =load ('r22p5n5');% 
     end 
     
%------------------------------------------------------------------------------------------------------------------------------------------------------
    

Ident=A(:,9); %The final column of A which associates each traced particle an indentification number every frame.
Y=(Ynpixels-A(:,1))*mp;% this vector gives Y-Coordinate data from the input file A in microns.
X=A(:,2)*mp;% this vector gives X-Coordinate data from the into file A in microns.The Y-axis is inverted.
A(:,1)=Ynpixels-A(:,1);
T=A(:,8);
XY=(X.^2+Y.^2).^0.5;% This is to create a 2D position vector.

Newcol=zeros(length(Y),1); %This creates a column vector the same length as the columns in A
for i=1:5 % This section adds columns to the Vector formed from the input file
A=[A Newcol]; %This tags on columns to vector A to store extra information
end

NTP=max(Ident);% total number of Tracks
Length=length(Ident);% number of rows of Ident, which is the vector which holds all the identification numbers in ascendng order
B=0;
B=1:NTP;% This is giong to become a vector holds the number of the row at which a given identification number stops occuring, that is the row in A at this the idn number stops occuring which is due to that particle bieng lost
B=B.*0;% This sets all the values of the vector to zero
ST=1:NTP;% This is giong to become a vector which holds all the row numbers where a track with a given id starts
ST=ST.*0;% This sets all the values of the vector to zero
FN=A(:,8);% 2nd last column of the orignaly imported matrix A, which gives a frame number for each invidual particle bieng tracted in a paticular frame
SFN=size(FN);% number of elements per column of A
MF=max(FN); %This gives the highest frame number in which a particle has been indentified, This means that either this is the last frame in the original tif file or it is the last frame of any importance.
k=1;
k2=1;% A counter variable

C=zeros(MF,NTP);

%-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
%The nested loop below fills the vector B, which holds the row number at
%which the particle with the given identification number is lost

for k=1:(NTP-1)
    
    while Ident(k2)== k %k is essentially a particle identifiction number
        k2=k2+1;
    end
    
       B(k)=k2-1;% This gives the row number at which the particle with IDN=k is lost
        
end
B(NTP)=Length;% This is to fill in the last row of B, the row number at which the final particle being tracked is lost, and this is the final value in that column
ST=0;% this is to set the vector to zero to prevent previous runs messing up future results
ST(1)=1;%This is the row number of A in which the first track begins

for p=2:NTP
ST(p)= B(p-1)+1;% ST is now a vector with the starting row number of each track kept within
end
TL=0;% this is to set the vector to zero to prevent previous runs messing up future results

% ST(i) is the row number of A where the track with id i is starts
TL= B-ST+1;% T(i) is the length of track i

%--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
%this section creates a vector (FTINV) which holds the identity numbers of tracks
%whose  frame length is greater than cutoff.
temp1=1;

cutoff=Num+1; % this means that for a track to be analysed it must be longer than Num +1
FTINV=0;% this is to set the vector to zero to prevent previous runs messing up future results
for k=1:NTP
    if TL(k)>= cutoff
        
        FTINV(temp1)=k;%this is where FTINV is first constructed
        
        temp1=temp1+1;
    end
end

NFTP=length(FTINV);%Number of filterd tracked particles, note some of the particles may infact be the same due to them being lost and found again


temp5=1;%% this is to set the value to zero to prevent previous runs messing up future results


% The secion below is to create a vector which holds the displacement
% acheived by all the filterd tracks over a the first set of frames up to
% MaxLength.Yhis is so that the distances achieved are all taken over the
% same time span
%--------------------------------------------------------------------------
MaxLength=Num;
Dist=0;
OAng=0;
XD=0;
YD=0;
Speed=0;

 XDT=0;
    
    YDT=0;
     
    AoTT=0;
     


counter=1;
for k2=1:length(FTINV)
  IDN=FTINV(k2);  
  
  XD=0;
  YD=0;
  AoT=0;
  Di=0;

  %---------------------------------------------------------------------------------------------------
  %This section creates vectors that correspond to the difference bewtween
  %the inital value of the track  and the highest possible value that is a
  %multiple of maxlength
  Co=floor(TL(IDN)/MaxLength);% floor rounds down
  
  XD2(k2)=-X(ST(IDN))+X(ST(IDN)+Co*MaxLength);
  
  YD2(k2)=-Y(ST(IDN))+Y(ST(IDN)+Co*MaxLength);
  
  Dist2(k2)=((XD2(k2)^2)+(YD2(k2)^2)).^0.5 ;
  
  if Dist2(k2)>= mindisp2
  AoT3(tempA)=atan2(YD2(k2),XD2(k2));
  tempA=tempA +1;
  end
  %----------------------------------------------------------------------------------------------------
   for i2=1:TL(IDN)-MaxLength+1 %Tracklength-Time scale in frames+1
 
    
    START=ST(IDN)+i2-1;% start= row number at which track begins +i2-1
    
    XD(i2)=-X(START)+X(START+MaxLength);
    
    
    YD(i2)=-Y(START)+Y(START+MaxLength);
    
    
   
    AoT(i2)=atan2(YD(i2),XD(i2));
    
    disc=AoT(i2);
    if AoT(i2)<0
       AoT(i2)= -abs(disc)+2*pi;
    end
     
    Di(i2)=((XD(i2)^2)+(YD(i2)^2))^0.5 ;
    
     AoT2(i2)=atan2(YD(i2),XD(i2));
    
    
    XDT(counter)=XD(i2);
    
    YDT(counter)=YD(i2);
     
    AoTT(counter)=AoT2(i2);
     
    counter=counter+1;
   end
  
   if mean(Di)>mindisp
             
  meanAoT(counter2)= mean(AoT);
   counter2=counter2+1;
    
   end
    
     
end
Dist=((XDT.^2)+(YDT.^2)).^0.5 ;
    
     
     OAng=atan2(YDT,XDT);
     Speed=(Dist)/(MaxLength/fps);



%the section below is to remove the tracks from Dist,OXD,OYD and OAng that have a
%displacement less than mindisp
%---------------------------------------------------
% Distance in microns, below which particle tracks that travel a distance less than are ignored

ND=length(Dist);% Number of tracks in Dist



for k=1:ND
    if (Dist(k)> mindisp) && (Dist(k) < F*MaxLength)
        
       
      
            
    DistFT(tempI) = Dist(k);
      
        OAngFT(tempI)=OAng(k);
        
         SpeedFT(tempI)=Speed(k);
        
        tempI=tempI+1;
        
        
        
    end
end

%----------------------------------------Section Track Plots----------------------------------------------------------------------------------------------
%This section creates 3 Tracking plots.

if round==1;
    if Plotyes==1
for i=1:length(FTINV)
         %fprintf('%d\n',i);
      
   
         
  IDN2=FTINV(i);
  ST(IDN2);
  B(IDN2);
   figure(9);
   plot(mp*A(ST(IDN2): B(IDN2),2),mp*A(ST(IDN2):B(IDN2),1),'--','linewidth',1.5),title(strcat(' Plot of Tracks',ET2  )),xlabel('Coordinates(Microns)'),ylabel('Coordinates(Microns)')
    
    plot(mp*A(ST(IDN2),2),mp*A(ST(IDN2),1),'mo') % plot pink circle at initial point            
            plot(mp*A((B(IDN2)),2),mp*A((B(IDN2)),1),'mo',...
                'MarkerEdgeColor','k',...
                'MarkerFaceColor',[.49 1 .63])
    axis image;
 hold all;

 clc
         
end
    end
end
%--------------------------------------------------------------------------------------------------------------------------------------
  if round==2;
    if Plotyes==1
for i=1:length(FTINV)
         %fprintf('%d\n',i);
      
   
         
  IDN2=FTINV(i);
  ST(IDN2);
  B(IDN2);
   figure(2);
    plot(mp*A(ST(IDN2): ST(IDN2)+MaxLength,2),mp*A(ST(IDN2):ST(IDN2)+MaxLength,1),'--','linewidth',1.5),title(strcat(' Plot of Tracks',ET  )),xlabel('Coordinates(Microns)'),ylabel('Coordinates(Microns)')
    
    plot(mp*A(ST(IDN2),2),mp*A(ST(IDN2),1),'mo') % plot pink circle at initial point            
            plot(mp*A((ST(IDN2)+MaxLength),2),mp*A((ST(IDN2)+MaxLength),1),'mo',...
                'MarkerEdgeColor','k',...
                'MarkerFaceColor',[.49 1 .63])
    axis image;
 hold all;

 clc
         
end
    end
    end   
%--------------------------------------------------------------------------------------------------------------------------------------
if round==3;
    if Plotyes==1
for i=1:length(FTINV)
         %fprintf('%d\n',i);
      
   
         
  IDN2=FTINV(i);
  ST(IDN2);
  B(IDN2);
   figure(1);
    plot(mp*A(ST(IDN2): ST(IDN2)+MaxLength,2),mp*A(ST(IDN2):ST(IDN2)+MaxLength,1),'--','linewidth',1.5),title(strcat(' Plot of Algae Tracks Over 8 Seconds, Squeezing Frequency of 1 Hz',ET)),xlabel('Coordinates(Microns)'),ylabel('Coordinates(Microns)')
    
    plot(mp*A(ST(IDN2),2),3.34*A(ST(IDN2),1),'mo') % plot pink circle at initial point            
            plot(mp*A((ST(IDN2)+MaxLength),2),mp*A((ST(IDN2)+MaxLength),1),'mo',...
                'MarkerEdgeColor','k',...
                'MarkerFaceColor',[.49 1 .63])
    
    axis image;
 hold all;

 clc
         
end
    end
end 
%--------------------------------------------------------------------------------------------------------------------------------------
    

   end
%-------------------------------------------Section  Relative Parrallel:Perpinduclar Direction Histogram Section-----------------------------------------------------------------------------------------------------------
%This Section below splits the angles of trajectorys obtained into 4 bins.

NOAngFT=0;
a1=0;
a2=0;
a3=0;
a4=0;
for i=1:length(OAngFT)
    
          if FA+pi/4>= pi
    if OAngFT(i)>=(FA-pi/4)&& OAngFT(i)<=pi
        NOAngFT(i)=FA;
        a1=a1+1;
    end
    
    if OAngFT(i)<(FA+pi/4)-2*pi 
        NOAngFT(i)=FA;
        a1=a1+1;
    end
    
    if OAngFT(i)>=(FA-pi-pi/4)&& OAngFT(i)<=(FA-pi+pi/4)
        NOAngFT(i)=FA+pi;
        a2=a2+1;
    end
    
    if OAngFT(i)>=(FA-pi/2-pi/4)&& OAngFT(i)<=(FA-pi/2+pi/4)
        NOAngFT(i)=FA-pi/2;
        a3=a3+1;
    end
    if  OAngFT(i)<((FA-pi-pi/2)+pi/4)&& OAngFT(i)>=(FA+pi/4)-2*pi 
        NOAngFT(i)=(FA+pi/2);
        a4=a4+1;
    end
          end
      
      if FA+pi/4< pi && FA-pi/4 >0
       
    if OAngFT(i)>=(FA-pi/4)&& OAngFT(i)<=(FA+pi/4)
        NOAngFT(i)=FA;
        a1=a1+1;
    end   
    
    
      if OAngFT(i)>=(FA+pi/4)
        NOAngFT(i)=FA;
        a2=a2+1;
    end 
    
     if OAngFT(i)<=(FA+pi)-2*pi
        NOAngFT(i)=FA;
        a2=a2+1;
    end 
    
        if OAngFT(i)>(FA+pi)-2*pi && OAngFT(i)<(FA+pi)-1.5*pi 
        NOAngFT(i)=FA;
        a3=a3+1;
        end 
        
    
         if OAngFT(i)<(FA-pi/4)&& OAngFT(i)>=0
        NOAngFT(i)=FA;
        a4=a4+1;
         end   
          
         if OAngFT(i)>(FA+pi)-1.5*pi && OAngFT(i)<=0
        NOAngFT(i)=FA;
        a4=a4+1;
         end   
         
         
    
         
          
      end
       
     
end
%------------------------------------------------------------------------------------------------------------------------------------------------------
%----------------------------------Section Trajectory and Speed Graphs--------------------------
%------------------------------------------------------------------------------------------------------------------------------------------------------
figure(3);
hist(SpeedFT,14),xlabel('Speed  (Microns/Second)'),...
ylabel('Number Per Bin'),title(strcat('Histogram of  Speed ',ET2,ET,ET3))



figure(4);
hist(SpeedFT,14),xlabel('Speed Over 6 Seconds (Microns/Second)'),...
ylabel('Number Per Bin'),title('Histogram of Speed Over 4 Seconds only 40Microns/s +  ')


figure (5);
hist(OAngFT,24),xlabel('Angle of trajectory(Radians)'),...
ylabel('Number Per Bin'),title(strcat('Histogram of  Angle of Trajectory Over 0.33sec,Squeezeing Frequency 3Hz ',ET),'FontSize',10)

%figure (6);
%hist(OAngFT,10),xlabel('Angle of trajectory(Radians)'),...
%ylabel('Number Per Bin'),title('Histogram of Angle of Trajectory over 4 Seconds only 40Microns/s + ')



figure (14);
hist(NOAngFT,4),xlabel('Angle of trajectory(Radians)'),...
ylabel('Number Per Bin'),title(strcat('Histogram of  Angle of Trajectory ',ET))


%------------------------------------------------------------------------------------------------------------------------------------------------------

%--------------------MSD Calculation Section-------------------------------
%--------------------------------------------------------------------------
MSDyes=1;% If this=1 then MSD data is collected

MSDTLF=MSDF;% MSD track length Filter in frames.This is the number of frames above which a given track must last before it has its msd analysed
MSDAFL=MSDL;% This is the number of frames over which the MSD of a given track is taken

%MSDAFL must be equal to or less than MSDTLF. Both must be less than the
%number of frames in the longest track
Countthis=0;
ATI=0;

IDNM=0;
AMSDMV=MSDAFL;
MSDA=0;
MSDA=[1:MSDAFL,1:4];
MSDA=MSDA.*0;

%---------------------------------------------------------------------------------------------------------------------------------------------------

        Countthis1=0;
        
        Countthis2=0;
        pcounter=0;
%--------------MSD normal way---------------
for k=1:(NTP-1);
    
    if TL(k)>=MSDTLF %this is to ensure that the only tracks that are analysed are those of length in frames greater than MSDTLF
        
     pcounter=pcounter+1;
        
        nLags=TL(k)-1;% For the given particle currently under inverstigation to find the msd maximum number of lags if the track length -1
        
        
        
        
      
        for j=1:nLags
            
            Countthis1=Countthis1+1;
           
            
            XMSD(j)=mean((X(ST(k)+j:B(k))-X(ST(k):B(k)-j)).^2);
            
            YMSD(j)=mean((Y(ST(k)+j:B(k))-Y(ST(k):B(k)-j)).^2);
            
            XYMSD(j)=mean((XY(ST(k)+j:B(k))-XY(ST(k):B(k)-j)).^2);
            
            MI(Countthis1,1)=((A(ST(k)+j,8))-A(ST(k),8))*LagTI;
               
            MI(Countthis1,2)=XMSD(j);
           
            MI(Countthis1,3)=YMSD(j);
             
            MI(Countthis1,4)=XYMSD(j);
            
            MI(Countthis1,5)=k; % column 5 is the the indentifiaction number of the particle in the corresponding rows
            
            %Here we use j in order to find the average MSD
            %when j = 
            
            
                 if j<=MSDAFL
                     
            Countthis2=Countthis2+1;
                
            MSD2(Countthis2,1)=MI(Countthis1,1);
               
            MSD2(Countthis2,2)=XMSD(j);
           
            MSD2(Countthis2,3)=YMSD(j);
             
            MSD2(Countthis2,4)=XYMSD(j);
            
            MSD2(Countthis2,5)=k; % column 5 is the the indentifiaction number of the particle in the corresponding rows
            
            MSDA(j,1)=j*LagTI;    
            MSDA(j,2)=MSDA(j,2)+MSD2(Countthis2,2);
            MSDA(j,3)=MSDA(j,3)+MSD2(Countthis2,3);   
            MSDA(j,4)=MSDA(j,4)+MSD2(Countthis2,4);
            
                
                 end
            
            
        end
      
        
    end
    

        
        
        
  








end
            MSDA(:,2)=MSDA(:,2)./pcounter;
            MSDA(:,3)=MSDA(:,3)./pcounter;   
            MSDA(:,4)=MSDA(:,4)./pcounter;
            
            MSDA2=MSDA(1:MSDAFL,1:4);
            
save FullMSD.txt MI -ascii
save ShortMSD.txt MSD2 -ascii
save AverageMSD.dat MSDA2 -ascii

loglog(MSDA(:,1),MSDA(:,4)),xlabel('Lag Time (Seconds)'),...
ylabel('2D MSD (Microns)^2'),title(strcat('Average 2 Dimensional MSD vs Lag Time'),'FontSize',10)
%----------------------------------------------------------------------------------------------------------------------------------------------------------------------
